<?php
/**
 * Created by PhpStorm.
 * User: huimingdeng
 * Date: 2019/3/29
 * Time: 20:58
 */

class Route
{
    protected $redis; // 安装 redis 客户端 编译安装 和服务端 yum install redis
    protected $server;

    public function run(){
        $this->server = new Server('0.0.0.0', '9600');
        $this->server->set(['work_num'=>4]);
        // $this->server->on('open', 'start');
        // echo 'test';
    }

    public function workerStart($server, $worker_id){
        $this->redis = new Redis();
        include __DIR__.'Round.php';
        // $this->redis->setOption(); //设置超时时间，设置 socket 超时时间
        $this->redis->pconnect('127.0.0.1',6378);
        // redis 连接池保护服务，超过则舍弃等
    }
    /**
     * 返回URL
     */
    public function returnUrl()
    {
        // 配合 Redis
        $arr = $this->redis->smembers("im_service");
        // $arr = ['1.1.1.1','2.2.2.2','3.3.3.']; // 测试
        Round::select($arr); // 数组从 Redis 获取
    }

    public function open($server, $request){

    }
    /**
     * JWT 证书颁发: 签发者，算法签名，签发时间等
     * 
     */
    public function issue(){
        $key = "ming12345";
        $time = tiem();
        $token = array(
            "iss" => "http://ming.com",
            "aud" => "http://ming.cn",
            "iat" => $time, // 签发时间
            "nbf" => $time, //生效时间
            "exp" => $time+7200, // 过期时间
            "data" => [
                "uid" => $id,
                "name" => 'ming',
                "service_url" => $url['ip'].":".$url['port'],
                // ...
            ]
        );
        return \Firebase\JWT\JWT::encode($token,$key);
    }

    /**
     * @param $request
     * @param $response
     */
    public function request($request, $response){
    	// 设置请求头
        $response->header('Access-Control-Allow-Origin', "*");// 允许所有
        $response->header('Access-Control-Allow-Methods', "GET,POST,OPTIONS");
        
        $data = $request->post;
        switch ($data['method']) {
            case 'login':
                // 1. 权限验证，颁发 token ，此时测试是忽略验证的
                    $url = json_decode($this->returnUrl(), true);
                    $token = $this->issue($data['id']);
                // 2. 通过算法返回服务器地址跟 token 
                    // 轮询或根据机器状态(定时上报状态)
                    $this->returnUrl();
                break;
            
            default:
                # code...
                break;
        }
    }

    /**
     * @param $server
     * @param $frame
     */
    public function message($server, $frame){
        $data = json_encode($frame->data,true);
        $fd = $frame->fd;
        switch ($data['method']) {
            case 'register':
                // 假设使用 Redis Set，命令操作 或 使用 hash
                // 组合 redis 的 key
                $service_key = 'service:'. $data['serviceName'];
                //              --------
                //                 |______ 自定义前缀
                echo $service_key;
                $value = json_encode([
                    'ip' => $data['ip'],
                    'port' => $data['port']
                ]);
                // ip+port 区分服务 eg. 192.168.1.128:9800 192.168.1.128:9801

                $this->redis->sadd($service_key, $value);
                $redis = $this->redis;
                // 会存在宕机的情况，主动清除
                $server->tick(3000, function($id, $redis, $server, $service_key, $fd) { // 非一次性定时器应该多少时长清除？业务需求设置
                    // 先检测 fd 是否存活  -- IM server 端的存活状态 --掉线删除
                    if (!$server->exist($fd)){
                        // 删除 redis 当中的服务信息
                        // var_dump('IM 宕机了');
                        $redis->del($service_key); //SREM
                        // 清除定时器
                        $server->clearTimer($id);
                    }
                }, $redis, $server, $service_key, $fd); 

                break;
            
            default:
                # code...
                break;
        }
    }

    public function close($server, $fd){

    }
}